/*
 * @Author: huangwei
 * @Date: 2021-06-21 20:19:05
 * @LastEditors: huangwei
 * @LastEditTime: 2021-06-30 11:16:17
 * @Description: 高效率点图层
 */
import type { BindMap } from 'types'

import L from 'leaflet'
import {
    graphic,
    graphicLayer,
    circleStyle,
    cloverStyle,
    imageStyle,
    // @ts-ignore
} from '@supermap/iclient-leaflet'

// 点样式
const STYLES: any = {
    circle: circleStyle,
    clover: cloverStyle,
    image: imageStyle,
}

function createStyle(style: any, idx?: number) {
    if (typeof style === 'function') style = style(idx)

    // 数组
    if (Array.isArray(style)) style = style[idx || 0] || style[0]

    // 返回的是个style
    if (style.getStyle) return style.getStyle()

    // 返回的是变量
    if (STYLES[style.type]) return STYLES[style.type](style).getStyle()
}

export default class HEGraphicsPlugin {
    map: any
    options: any

    // 私有变量
    _layer: any
    _id: number

    // 支持的事件
    onClick!: (graphic: any) => void

    constructor(vm: BindMap, opt_options = {}) {
        this.map = vm.map
        this.options = opt_options
        this._id = 0
    }

    get layer() {
        if (!this._layer) {
            // 创建并添加图层
            this._layer = graphicLayer([], {
                render: 'canvas',
                onClick: (graphic: any) => {
                    if (this.onClick) this.onClick(graphic)
                },
                ...this.options,
            }).addTo(this.map)
        }
        return this._layer
    }

    // 创建一个新的实例
    public create(options: any) {
        return new HEGraphicsPlugin(
            { map: this.map } as any,
            options || this.options
        )
    }

    // 添加
    public addGraphics(points: any[], styles: any, attrs: any) {
        if (!Array.isArray(points) || points.length === 0) return
        if (!Array.isArray(points[0])) points = [points]

        const gs = points.map((point: any, i) => {
            // 样式
            let style = styles
            if (Array.isArray(styles)) style = styles[i]
            // 属性
            let attr = attrs
            if (Array.isArray(attrs)) attr = attrs[i]

            return graphic({
                id: ++this._id,
                latLng: L.latLng(point[1], point[0]),
                style: createStyle(style, i),
                attributes: attr,
            })
        })
        // 添加图像
        this.layer.addGraphics(gs)

        // 返回构建的图形
        return gs
    }

    // 移除要素，graphics为空则删除所有
    public removeGraphics(graphics: any) {
        if (!this._layer) return
        this._layer && this._layer.removeGraphics(graphics)
    }

    // 设置样式
    public setStyle(graphics: any[], style: any) {
        if (!this._layer) return

        if (!Array.isArray(graphics)) {
            graphics = [graphics]
        }
        graphics.forEach((g: any, i) => {
            g.setStyle(createStyle(style, i))
        })
    }

    // 销毁
    public destroy() {
        if (!this._layer) return

        this.layer.clear()
        this.layer.remove()
        this._layer = undefined
    }
}
